package com.maikang.exammall.task.scheduler;

import com.maikang.exammall.entity.constant.BillStatus;
import com.maikang.exammall.entity.constant.OrderStatus;
import com.maikang.exammall.entity.dto.order.IdOnlyDTO;
import com.maikang.exammall.repository.BillRepository;
import com.maikang.exammall.repository.CommissionRepository;
import com.maikang.exammall.repository.OrderItemRepository;
import com.maikang.exammall.repository.OrderRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

@Component
@Log4j2
@RequiredArgsConstructor
public class UpdateOrderScheduler {
    private final OrderRepository orderRepository;
    private final BillRepository billRepository;
    private final OrderItemRepository orderItemRepository;
    private final CommissionRepository commissionRepository;


    @Scheduled(initialDelay=1000L * 120, fixedRate = 1000L * 300) // 5min
    @Transactional(rollbackFor = Exception.class)
    public void closeUnpaidAndExpiredOrdersAndBills() {
        log.info("executing closeUnpaidAndExpiredOrdersAndBills...");
        long start = System.currentTimeMillis();


        List<IdOnlyDTO> bills = billRepository.findUnpaidAndExpiredBills();
        List<Long> billIds = new ArrayList<>();
        List<Long> orderIds = new ArrayList<>();
        for (IdOnlyDTO bill : bills) {
            billIds.add(bill.getId());
            orderIds.add(bill.getOrderId());
        }
        billRepository.updateStatusByIds(BillStatus.PAY_EXPIRED, billIds);
        orderRepository.updateStatusByIds(OrderStatus.CLOSED, orderIds);
        orderItemRepository.updateStatusByOrderIdAndStatus(OrderStatus.TO_PAY, OrderStatus.CLOSED, orderIds);
        log.info("closeUnpaidAndExpiredOrdersAndBills done, it took {} milliseconds", System.currentTimeMillis() - start);
    }

//    @Scheduled(initialDelay = -1L, fixedRate = 24 * 3600 * 1000L) // 每天一次
    @Scheduled(cron = "0 0 0 * * ?")  // 每天凌晨跑一次
    @Transactional(rollbackFor = Exception.class)
    public void updateOrderStatusFromPaidToFinishExam() {
        log.info("executing updateOrderStatusFromPaidToFinishExam...");
        long start = System.currentTimeMillis();
        List<IdOnlyDTO> orderItems = orderItemRepository.findExaminedOrderItem();

        List<Long> orderItemIds = new ArrayList<>();
        List<Long> orderIds = new ArrayList<>();
        orderItems.forEach(item -> {
            orderItemIds.add(item.getId());
            orderIds.add(item.getOrderId());
        });
        orderRepository.updateStatusByIds(OrderStatus.EXAMINED_TO_COMMENT, orderIds);
        orderItemRepository.updateStatusByIds(OrderStatus.EXAMINED_TO_COMMENT, orderItemIds);
        commissionRepository.updateStatusByOrderItemIds(orderItemIds, OrderStatus.EXAMINED_TO_COMMENT);
        log.info("updateOrderStatusFromPaidToFinishExam done, it took {} milliseconds", System.currentTimeMillis() - start);
    }
}
